package cn.dengta.context.auth;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.dengta.common.context.Context;
import cn.dengta.common.web.Page;
import cn.dengta.common.web.mvc.EmptyView;
import cn.dengta.webapp.base.util.ExcelUtil;
import cn.dengta.webapp.base.util.ExcelUtil.ExcelConfig;
import cn.dengta.webapp.base.util.Export;
import me.codeplayer.util.X;
import org.springframework.lang.Nullable;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class ExportInterceptor implements HandlerInterceptor {

	public static final String EXPORT_EXCEL_TITLE = "exportExcelTitle";
	public static final String EXPORT_EXCEL_LIST = "exportExcelList";
	public static final String EXPORT_PARAM = "export";
	/**
	 * 该属性指示设置的 EXPORT_EXCEL_TITLE 数组是否是键值对形式
	 */
	public static final String EXCEL_TITLE_AS_PAIRS = "excelTitleAsPairs";

	public static boolean isExport(HttpServletRequest request) {
		return "true".equals(request.getParameter(EXPORT_PARAM));
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) {
		if (handler instanceof HandlerMethod && isExport(request)) {
			Method method = ((HandlerMethod) handler).getMethod();
			final Export export = method.getAnnotation(Export.class);
			final boolean exportNeeded = export != null;
			if (exportNeeded) {
				List<Object> list = X.castType(request.getAttribute(EXPORT_EXCEL_LIST));
				if (list == null && modelAndView != null) {
					Page<Object> page = X.castType(modelAndView.getModelMap().get(Context.internal().getPageAttr()));
					list = page.getList();
				}
				if (list == null) {
					list = Collections.emptyList();
				}
				String pairsStr = export.value();
				final boolean inMethod = Export.IN_METHOD.equals(pairsStr);
				final boolean disableCache = Export.NO_CACHE.equals(export.key());
				ExcelConfig cfg;
				if (!inMethod && pairsStr.length() > 0) {
					cfg = ExcelConfig.getCached(request, export.key(), pairsStr, disableCache, null);
				} else {
					cfg = ExcelConfig.getCached(request, export.key(), null, disableCache, (builder) -> {
						final String[] title = inMethod ? (String[]) request.getAttribute(EXPORT_EXCEL_TITLE) : export.values();
						if (title == null || title.length == 0) {
							throw new IllegalArgumentException("invalid @Export config:" + method.getName());
						}
						Object excelTitleAsPairs = request.getAttribute(EXCEL_TITLE_AS_PAIRS);
						return builder.propertyPairs(!Boolean.TRUE.equals(excelTitleAsPairs), title);
					});
				}
				ExcelUtil.export(list, cfg, export.filename(), true);
				if (modelAndView != null) {
					modelAndView.setViewName(null);
					modelAndView.setView(EmptyView.INSTANCE);
				}
			}
		}
	}

}
